package art_of_java_concurrent_programming.lock.stamped_lock;

import java.util.concurrent.locks.StampedLock;

/**
 * @author lixiangke
 * @date 2018/12/21
 */
public class Point {
    public double x, y;
    public final StampedLock stampedLock = new StampedLock();

    void move(double deltaX, double deltaY) {
        long stamp = stampedLock.writeLock();
        try {
            x += deltaX;
            y += deltaY;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }

    double distanceFromOrigin() {
        // 试图尝试一次乐观读
        long stamp = stampedLock.tryOptimisticRead();
        double currentX = x;
        double currentY = y;
        // 上面 2 行 currentX 和 currentY 未必一致，因为读取 x 后 y 可能被修改
        // 判断 stamp 在读过程发生期间是否被修改过，未被修改过返回true
        if (!stampedLock.validate(stamp)) {
            // 可以死循环一直乐观读
            // 这里采用将锁变为悲观锁
            stamp = stampedLock.readLock();
            try {
                currentX = x;
                currentY = y;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        return Math.sqrt(currentX * currentX + currentY * currentY);
    }




}
